//This should be run on the infected machine in order to generate the BotKey that will be used for decoding modules

#include <Windows.h>

#include <stdio.h>
#include <stdlib.h>

#include <iphlpapi.h>
#pragma comment(lib, "IPHLPAPI.lib")

#include <wincrypt.h>
#pragma comment(lib, "crypt32.lib")


#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

#define BUFSIZE 1024
#define SHA256LEN  64
#define SHA256_ASCII_LEN SHA256LEN * 2 + 1

DWORD make_bot_key(BYTE *buffer, DWORD buffer_size, char bot_id[SHA256_ASCII_LEN])
{
    DWORD dwStatus = 0;
    BOOL bResult = FALSE;
    HCRYPTPROV hProv = 0;
    HCRYPTHASH hHash = 0;

    BYTE rgbHash[SHA256LEN] = { 0 };
    DWORD cbHash = 0;

    wchar_t info[] = L"Microsoft Enhanced RSA and AES Cryptographic Provider";
    if (!CryptAcquireContextW(&hProv, NULL, info, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
        dwStatus = GetLastError();
        CryptReleaseContext(hProv, 0);
        return dwStatus;
    }

    if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
        dwStatus = GetLastError();
        CryptReleaseContext(hProv, 0);
        return dwStatus;
    }

    if (!CryptHashData(hHash, buffer, buffer_size, 0)) {
        dwStatus = GetLastError();
        CryptReleaseContext(hProv, 0);
        CryptDestroyHash(hHash);
        return dwStatus;
    }
    cbHash = SHA256LEN;
    if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) {
        for (DWORD i = 0; i < cbHash; i++) {
            snprintf(bot_id, SHA256_ASCII_LEN, "%02X", rgbHash[i]);
            bot_id += 2;
        }
    }
    else {
        dwStatus = GetLastError();
    }
    CryptReleaseContext(hProv, 0);
    return dwStatus;
}

int main()
{
    PIP_ADAPTER_INFO pAdapterInfo;
    PIP_ADAPTER_INFO pAdapter = NULL;
    DWORD dwRetVal = 0;

    ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
    pAdapterInfo = (IP_ADAPTER_INFO *)MALLOC(sizeof(IP_ADAPTER_INFO));
    if (pAdapterInfo == NULL) {
        fprintf(stderr, "Error allocating memory needed to call GetAdaptersinfo\n");
        return 1;
    }
    ZeroMemory(pAdapterInfo, sizeof(IP_ADAPTER_INFO));

    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
        FREE(pAdapterInfo);
        pAdapterInfo = (IP_ADAPTER_INFO *)MALLOC(ulOutBufLen);
        if (pAdapterInfo == NULL) {
            fprintf(stderr, "Error allocating memory needed to call GetAdaptersinfo\n");
            return 1;
        }
        ZeroMemory(pAdapterInfo, sizeof(IP_ADAPTER_INFO));
    }

    if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) != NO_ERROR) {
        fprintf(stderr, "Warning: GetAdaptersInfo failed with error: %d.\nContinuing with empty buffer...\n", dwRetVal);
        // TrickBot will continue generating even if getting adapter info has failed...
    }
    char bot_id[SHA256_ASCII_LEN] = { 0 };
    if ((dwRetVal = make_bot_key((BYTE*)&pAdapterInfo->AdapterName, 0x194, bot_id)) == NO_ERROR) {
        printf("botkey=%s\n", bot_id);
    }
    if (pAdapterInfo)
        FREE(pAdapterInfo);
    system("pause");
    return dwRetVal;
}
